#ifndef __HOT_MANAGER__
#define __HOT_MANAGER__

#include "Util.hpp"
#include "Config.hpp"
#include "DataManager.hpp"
#include <unistd.h>
#include <time.h>
extern hhbcloud::DataManager* data; // 创建一个全局的数据管理类，便于对数据的操作

namespace hhbcloud
{
    class HotManager // 热点管理类
    {
    public:
        HotManager()
        {
            // 备份文件，压缩文件，最后一次访问时间，压缩文件前缀均可从配置文件中读取
            Config* config = Config::GetInstance();
            _back_dir = config->GetBackDir();
            _pack_dir = config->GetPackDir();
            _hot_time = config->GetHotTime();
            _packfile_suffix = config->GetPackfileSuffix();

            // 如果压缩文件目录和备份文件目录不存在，则创建目录
            FileUtil fu1(_back_dir);
            fu1.CreateDirectory(); // 函数内部对文件存在做了判断，若文件已经存在，则直接返回
            FileUtil fu2(_pack_dir);
            fu2.CreateDirectory();
        }

        // 运行模块
        bool RunMoudle()
        {
            // 热点管理需要不断循环检测备份文件目录下的文件因此是一个死循环
            while (1)
            {
                // 首先浏览指定目录下的所有文件
                FileUtil fu(_back_dir);
                std::vector<std::string> array;
                fu.ScanDirectory(&array);

                for (auto& e : array) // 循环每个文件，判断是否是热点文件，是否需要压缩
                {
                    if (HotJundge(e) == false)
                    {
                        // 热点文件 直接跳过，不用管
                        continue;
                    }

                    Backinfo info;
                    // 此时为非热点文件
                    if (data->GetOneByRealpath(e, &info) == false) //从备份信文件中无法找到，文件存在，但是没有备份
                    {
                        info.NewBackinfo(e);// 给文件创建一个备份信息
                    }

                    // 此时info中的已经有了备份信息(在备份信息文件中找到的， 或者对遗漏的文件创建的备份信息)
                    FileUtil tmp(e);
                    tmp.Compress(info._pack_path); // 对文件进行压缩
                    // 删除原来的备份文件
                    tmp.Remove();
                    info._pack_flag = true;
                    data->Update(info);
                }
                usleep(1000); // 为了避免空目录持续循环，造成cpu资源消耗过高，间隔1000ms也就是0.1s
            }
            return true;
        }
    private:
        bool HotJundge(const std::string& filename)
        {
            FileUtil fu(filename);
            time_t last_atime = fu.LastATime();
            time_t cur_time = time(nullptr);
            if ((cur_time - last_atime) > _hot_time)
            {
                // 最后一次访问时间 - 当前时间 如果大于 热点判断时间，说明为非热点文件，需要压缩
                return true;
            }
            return false;
        }
    private:
        std::string _back_dir; // 备份文件，热点管理类需要从备份文件中获取所有文件判断热点，所以需要备份文件
        std::string _pack_dir;  // 压缩文件，热点管理类对非热点文件进行压缩处理，并存放在压缩目录下
        std::string _packfile_suffix; // 压缩文件的后缀
        int _hot_time; // 热点判断时间
    };
}

#endif